package com.mars.upms.rpc.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import tk.mybatis.mapper.entity.Condition;

import com.mars.base.common.exception.AppException;
import com.mars.base.common.utils.PasswordUtils;
import com.mars.base.common.utils.RandomUitl;
import com.mars.base.service.support.BaseService;
import com.mars.upms.dao.mapper.UpmsUserCompanyDeptAssignMapper;
import com.mars.upms.dao.mapper.UpmsUserGroupAssignMapper;
import com.mars.upms.dao.mapper.UpmsUserMapper;
import com.mars.upms.dao.mapper.UpmsUserRoleAssignMapper;
import com.mars.upms.dto.UpmsUserDto;
import com.mars.upms.entity.UpmsUser;
import com.mars.upms.entity.UpmsUserCompanyDeptAssign;
import com.mars.upms.entity.UpmsUserGroupAssign;
import com.mars.upms.entity.UpmsUserRoleAssign;
import com.mars.upms.rpc.api.UpmsUserService;

@Service
public class UpmsUserServiceImpl extends BaseService<UpmsUser, Integer> implements UpmsUserService {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass()) ;

	@Autowired
	private UpmsUserMapper mapper;
	
	@Autowired
	private UpmsUserGroupAssignMapper assignMapper;
	
	@Autowired
	private UpmsUserCompanyDeptAssignMapper userCompanyDeptAssignMapper;
	
	@Autowired
	private UpmsUserRoleAssignMapper roleAssignMapper;
	
	@Override
	public UpmsUser insertSelective(UpmsUser entity) throws AppException {
		entity.setSalt(RandomUitl.uuid());
		//密码加密加盐，使用手机号码作为登陆账号，手机号码后4位为初始密码
		entity.setPassword(PasswordUtils.encodePassword(entity.getMobile().substring(entity.getMobile().length()-4), entity.getSalt()));
		return super.insertSelective(entity);
	}

	@Override
	public UpmsUser getAccount(String account) {
		return this.mapper.getAccount(account);
	}

	@Override
	public void batchResetPassword(Integer[] ids) {
		for (Integer id : ids) {
			UpmsUser user = this.selectById(id);
			if(null != user) {
				if(null != user.getMobile() && StringUtils.isNotEmpty(user.getMobile())) {
					String password = user.getMobile().substring(user.getMobile().length()-4) ;
					String slat = RandomUitl.uuid() ;
					String encodePassword = PasswordUtils.encodePassword(password, slat) ;
					
					this.mapper.batchResetPassword(user.getId(), encodePassword, slat) ;
				} else {
					logger.warn("该用户["+user.getRealName()+"]未设置手机号码，跳过重置密码");
				}
			}
		}
	}

	@Override
	public void batchUpdateStatus(Integer[] ids, Integer status) {
		this.mapper.batchUpdateStatus(ids, status);
	}

	@Override
	public void loginRecord(Integer id, String lastLoginIp) {
		this.mapper.loginRecord(id, lastLoginIp);
	}
	
	@Override
	public void addUsersToGroupAssign(UpmsUserDto dto) {
		List<UpmsUserGroupAssign> userGroupAssign = this.getUserGroupAssign(dto.getGroupId()) ;
		if(userGroupAssign != null && !userGroupAssign.isEmpty()) {
			//比较该组是否有重复用户，将重复用户去除后再加入到用户组中
			List<Integer> userIds = distinctGroupUsers(dto, userGroupAssign);
			if(null != userIds && !userIds.isEmpty()) {
				List<UpmsUserGroupAssign> recordList = new ArrayList<UpmsUserGroupAssign>();
				for (Integer userId : userIds) {
					UpmsUserGroupAssign entity = new UpmsUserGroupAssign() ;
					entity.setUserId(userId);
					entity.setGroupId(dto.getGroupId());
					recordList.add(entity) ;
				}
				this.assignMapper.insertList(recordList) ;
			}
		} else {
			List<UpmsUserGroupAssign> recordList = new ArrayList<UpmsUserGroupAssign>();
			List<Integer> userIds = dto.getUserIds();
			for (Integer userId : userIds) {
				UpmsUserGroupAssign entity = new UpmsUserGroupAssign() ;
				entity.setUserId(userId);
				entity.setGroupId(dto.getGroupId());
				recordList.add(entity) ;
			}
			this.assignMapper.insertList(recordList) ;
		}
		
	}
	
	public List<Integer> distinctGroupUsers(UpmsUserDto dto, List<UpmsUserGroupAssign> userGroupAssign) {
		List<Integer> userIds = new ArrayList<Integer>() ;
		if(userGroupAssign != null && !userGroupAssign.isEmpty()) {
			List<Integer> old = new ArrayList<Integer>() ;
			for (UpmsUserGroupAssign upmsUserGroupAssign : userGroupAssign) {
				old.add(upmsUserGroupAssign.getUserId());
			}
			
			Iterator<Integer> iterator = dto.getUserIds().iterator();
			while (iterator.hasNext()) {
				Integer integer = (Integer) iterator.next();
				if(old.contains(integer)) {
					iterator.remove();
				} else{
					userIds.add(integer) ;
				}
			}
		}
		return userIds ;
	}
	
	@Override
	public List<UpmsUserGroupAssign> getUserGroupAssign(Integer groupId) {
		Condition condition = new Condition(UpmsUserGroupAssign.class) ;
		condition.createCriteria().andEqualTo("groupId", groupId);
		return this.assignMapper.selectByCondition(condition);
	}
	
	@Override
	public void addUsersToCompanyDeptAssign(UpmsUserDto dto) {
		List<UpmsUserCompanyDeptAssign> userGroupAssign = this.getUserDeptAssign(dto.getDepartmentId()) ;
		if(userGroupAssign != null && !userGroupAssign.isEmpty()) {
			//比较该组织机构是否有重复用户，将重复用户去除后再加入到组织机构中
			List<Integer> userIds = distinctOrganizationUsers(dto, userGroupAssign);
			if(null != userIds && !userIds.isEmpty()) {
				List<UpmsUserCompanyDeptAssign> recordList = new ArrayList<UpmsUserCompanyDeptAssign>();
				for (Integer userId : userIds) {
					UpmsUserCompanyDeptAssign entity = new UpmsUserCompanyDeptAssign() ;
					entity.setUserId(userId);
					entity.setCompanyId(dto.getCompanyId());
					entity.setDepartmentId(dto.getDepartmentId());
					recordList.add(entity) ;
				}
				this.userCompanyDeptAssignMapper.insertList(recordList) ;
			}
		} else {
			List<UpmsUserCompanyDeptAssign> recordList = new ArrayList<UpmsUserCompanyDeptAssign>();
			List<Integer> userIds = dto.getUserIds();
			for (Integer userId : userIds) {
				UpmsUserCompanyDeptAssign entity = new UpmsUserCompanyDeptAssign() ;
				entity.setUserId(userId);
				entity.setCompanyId(dto.getCompanyId());
				entity.setDepartmentId(dto.getDepartmentId());
				recordList.add(entity) ;
			}
			this.userCompanyDeptAssignMapper.insertList(recordList) ;
		}
		
	}
	
	public List<Integer> distinctOrganizationUsers(UpmsUserDto dto, List<UpmsUserCompanyDeptAssign> organizationAssigns) {
		List<Integer> userIds = new ArrayList<Integer>() ;
		if(organizationAssigns != null && !organizationAssigns.isEmpty()) {
			List<Integer> old = new ArrayList<Integer>() ;
			for (UpmsUserCompanyDeptAssign userOrganizationAssign : organizationAssigns) {
				old.add(userOrganizationAssign.getUserId());
			}
			
			Iterator<Integer> iterator = dto.getUserIds().iterator();
			while (iterator.hasNext()) {
				Integer integer = (Integer) iterator.next();
				if(old.contains(integer)) {
					iterator.remove();
				} else{
					userIds.add(integer) ;
				}
			}
		}
		return userIds ;
	}
	
	@Override
	public List<UpmsUserCompanyDeptAssign> getUserCompanyAssign(Integer companyId) {
		Condition condition = new Condition(UpmsUserCompanyDeptAssign.class) ;
		condition.createCriteria().andEqualTo("companyId", companyId);
		return this.userCompanyDeptAssignMapper.selectByCondition(condition);
	}
	
	@Override
	public List<UpmsUserCompanyDeptAssign> getUserDeptAssign(Integer departmentId) {
		Condition condition = new Condition(UpmsUserCompanyDeptAssign.class) ;
		condition.createCriteria().andEqualTo("departmentId", departmentId);
		return this.userCompanyDeptAssignMapper.selectByCondition(condition);
	}

	@Override
	public void addUsersToRoleAssign(UpmsUserDto dto) {
		List<UpmsUserRoleAssign> userRoleAssigns = this.getUserRoleAssign(dto.getRoleId()) ;
		if(userRoleAssigns != null && !userRoleAssigns.isEmpty()) {
			//比较该组织机构是否有重复用户，将重复用户去除后再加入到组织机构中
			List<Integer> userIds = distinctRoleUsers(dto, userRoleAssigns);
			if(null != userIds && !userIds.isEmpty()) {
				List<UpmsUserRoleAssign> recordList = new ArrayList<UpmsUserRoleAssign>();
				for (Integer userId : userIds) {
					UpmsUserRoleAssign entity = new UpmsUserRoleAssign() ;
					entity.setUserId(userId);
					entity.setRoleId(dto.getRoleId());
					recordList.add(entity) ;
				}
				this.roleAssignMapper.insertList(recordList) ;
			}
		} else {
			List<UpmsUserRoleAssign> recordList = new ArrayList<UpmsUserRoleAssign>();
			List<Integer> userIds = dto.getUserIds();
			for (Integer userId : userIds) {
				UpmsUserRoleAssign entity = new UpmsUserRoleAssign() ;
				entity.setUserId(userId);
				entity.setRoleId(dto.getRoleId());
				recordList.add(entity) ;
			}
			this.roleAssignMapper.insertList(recordList) ;
		}
		
	}
	
	public List<Integer> distinctRoleUsers(UpmsUserDto dto, List<UpmsUserRoleAssign> roleAssigns) {
		List<Integer> userIds = new ArrayList<Integer>() ;
		if(roleAssigns != null && !roleAssigns.isEmpty()) {
			List<Integer> old = new ArrayList<Integer>() ;
			for (UpmsUserRoleAssign userRoleAssigns : roleAssigns) {
				old.add(userRoleAssigns.getUserId());
			}
			
			Iterator<Integer> iterator = dto.getUserIds().iterator();
			while (iterator.hasNext()) {
				Integer integer = (Integer) iterator.next();
				if(old.contains(integer)) {
					iterator.remove();
				} else{
					userIds.add(integer) ;
				}
			}
		}
		return userIds ;
	}

	@Override
	public List<UpmsUserRoleAssign> getUserRoleAssign(Integer roleId) {
		Condition condition = new Condition(UpmsUserRoleAssign.class) ;
		condition.createCriteria().andEqualTo("roleId", roleId);
		return this.roleAssignMapper.selectByCondition(condition);
	}

	@Override
	public UpmsUser getUserDetail(UpmsUserDto dto) {
		return this.mapper.getUserDetail(dto);
	}

	@Override
	public void updatePassword(Integer id, String oldPassword, String newPassword) {
		UpmsUser entity = this.selectById(id) ;
		
		if(!PasswordUtils.isPasswordValid(entity.getPassword(), oldPassword, entity.getSalt())) {
			throw new RuntimeException("新密码与原密码不一致") ;
		}
		
		String salt = RandomUitl.uuid() ;
		//密码加盐组成加密密码
		String encodePassword = PasswordUtils.encodePassword(newPassword, salt) ;
		UpmsUser newEntity = new UpmsUser() ;
		newEntity.setId(id);
		newEntity.setPassword(encodePassword);
		newEntity.setSalt(salt);
		
		Condition condition = new Condition(UpmsUser.class) ;
		condition.createCriteria().andEqualTo("id", id) ;
		
		this.mapper.updateByConditionSelective(newEntity, condition) ;
		
	}
	
	
}
